<script>
// 注入
import { defineComponent, ref, computed, nextTick, provide } from 'vue';
import { useNodeTreeStore } from 'src/stores/nodeTree';
import defaultProps from '../../common/defaultProps.ts';
import { computedGroupLayout } from '../../common/utils';
import html2pdf from 'html2pdf.js';
import RenderCom from 'src/pages/BiographicalNotes/components/RenderCom/RenderCom.vue';
import LinesComponent from 'src/pages/BiographicalNotes/components/LinesComponent/LinesComponent.vue';
import TemporaryGroup from 'src/pages/BiographicalNotes/components/TemporaryGroup/TemporaryGroup.vue';
import Shape from '../Shape/Shape.vue';
export default defineComponent({
  name: 'RootNode',
  components: { RenderCom, LinesComponent, TemporaryGroup, Shape },
  props: defaultProps,
  setup(_, ctx) {
    const nodeTreeStore = useNodeTreeStore();
    const el = ref(null);
    const exportToPdf = () => {
      showPages.value = false;
      nodeTreeStore.setActiveNode(null);
      document.body.blur();
      nextTick(async () => {
        await html2pdf().from(document.getElementById('a4')).save();
        showPages.value = true;
      });
    };
    const print = () => {
      showPages.value = false;
      nodeTreeStore.setActiveNode(null);
      document.body.blur();
      nextTick(() => {
        // 创建一个文档碎片
        const doc = document.createDocumentFragment();
        const body = document.body;
        const cloneNode = document.getElementById('a4').cloneNode(true);
        // 将body的所有子元素移除
        Array.from(body.children).forEach((child) => {
          doc.appendChild(child);
        });
        body.appendChild(cloneNode);
        window.print();
        //还原
        cloneNode.remove();
        Array.from(doc.children).forEach((child) => {
          body.appendChild(child);
        });
        showPages.value = true;
      });
    };
    ctx.expose({
      exportToPdf,
      print,
    });
    const dragover = (event) => {
      if (nodeTreeStore.from && nodeTreeStore.from.type === 'node') {
        event.preventDefault();
      }
    };
    const dragenter = (event) => {
      // console.log('dragenter', event);
      // console.log('nodeTreeStore', nodeTreeStore.from);
      if (nodeTreeStore.from && nodeTreeStore.from.type === 'node') {
        event.preventDefault();
      }
    };
    const drop = (event) => {
      if (nodeTreeStore.from && nodeTreeStore.from.type === 'node') {
        event.preventDefault();
        nodeTreeStore.addNode(event);
      }
    };
    const setActive = (node) => {
      nodeTreeStore.setActiveNode(node);
    };
    const style = computed(() => {
      return {
        ...nodeTreeStore.root.layout,
        backgroundColor: '#FFFFFF',
        // padding: nodeTreeStore.root.layout.padding + 'px',
        height: nodeTreeStore.root.layout.height + 'px',
        width: nodeTreeStore.root.layout.width + 'px',
      };
    });

    const showPages = ref(true);
    const pages = computed(() => {
      if (!showPages.value) return [];
      // 当model高度改变时，重新计算页面
      const count = Math.ceil(nodeTreeStore.root.layout.height / 1123);
      const arr = [];
      for (let i = 1; i < count; i++) {
        arr.push(i);
      }
      return arr;
    });
    const pageWidth = computed(() => {
      // return nodeTreeStore.root.layout.width - nodeTreeStore.root.layout.padding * 2;
      return nodeTreeStore.root.layout.width;
    });
    const pageHeight = computed(() => {
      // return nodeTreeStore.root.layout.height - nodeTreeStore.root.layout.padding * 2;
      return nodeTreeStore.root.layout.height;
    });
    provide('pageWidth', pageWidth);
    provide('pageHeight', pageHeight);
    // const DraggableContainerHeight = computed(() => {
    //   return nodeTreeStore.root.layout.height - nodeTreeStore.root.layout.padding * 2 + 'px';
    // });
    // const DraggableContainerWidth = computed(() => {
    //   return nodeTreeStore.root.layout.width - nodeTreeStore.root.layout.padding * 2 + 'px';
    // });
    const shapeRef = ref(null);
    const mousedown = (event) => {
      if (event.target === event.currentTarget) {
        nodeTreeStore.setActiveNode(nodeTreeStore.root);
        nodeTreeStore.setContextMenu(false);
      } else {
        return;
      }
      event.preventDefault();
      event.stopPropagation();
      nodeTreeStore.resizeTemporaryGroup();
      const rectInfo = event.target.getBoundingClientRect();
      const startX = event.clientX - rectInfo.x;
      const startY = event.clientY - rectInfo.y;
      let fist = true;
      nodeTreeStore.setTemporaryGroupLayout({
        x: startX,
        y: startY,
        width: 0,
        height: 0,
      });
      nodeTreeStore.setTemporaryGroupShow(true);
      const move = (event) => {
        if (fist) {
          fist = false;
          return;
        }
        let x = Number(event.clientX) - rectInfo.x;
        let y = Number(event.clientY) - rectInfo.y;
        let width = Math.abs(x - startX);
        let height = Math.abs(y - startY);
        if (x < startX) {
          nodeTreeStore.temporaryGroup.layout.x = x;
        }
        if (y < startY) {
          nodeTreeStore.temporaryGroup.layout.y = y;
        }
        nodeTreeStore.temporaryGroup.layout.width = width;
        nodeTreeStore.temporaryGroup.layout.height = height;
        // console.log('x', x, 'y', y);
      };
      const up = () => {
        document.removeEventListener('mousemove', move);
        document.removeEventListener('mouseup', up);
        nodeTreeStore.root.children.forEach((node) => {
          // nodeTreeStore.root.children.forEach((node) => {
          // const node = nodeTreeStore.treeMap[id];
          const { x, y } = node.layout;
          if (
            x >= nodeTreeStore.temporaryGroup.layout.x &&
            x <=
              nodeTreeStore.temporaryGroup.layout.x + nodeTreeStore.temporaryGroup.layout.width &&
            y >= nodeTreeStore.temporaryGroup.layout.y &&
            y <= nodeTreeStore.temporaryGroup.layout.y + nodeTreeStore.temporaryGroup.layout.height
          ) {
            nodeTreeStore.addTemporaryGroup(node);
          }
        });
        console.log(nodeTreeStore.temporaryGroup.children);
        if (nodeTreeStore.temporaryGroup.children.length > 0) {
          nodeTreeStore.temporaryGroup.layout = computedGroupLayout(
            nodeTreeStore.temporaryGroup.children,
          );
          const recursive = (node) => {
            if (!node.lock) {
              // 强行打断forEach
              throw false;
            }
            if (node.children && node.children.length > 0) {
              node.children.forEach((child) => {
                recursive(child);
              });
            }
          };
          try {
            nodeTreeStore.temporaryGroup.children.forEach((node) => {
              recursive(node);
            });
            nodeTreeStore.temporaryGroup.lock = true;
          } catch (lock) {
            nodeTreeStore.temporaryGroup.lock = lock;
          }
        } else {
          nodeTreeStore.resizeTemporaryGroup(false);
        }
      };
      document.addEventListener('mousemove', move);
      document.addEventListener('mouseup', up);
      return false;
    };
    const activeNode = computed(() => {
      return (
        nodeTreeStore.activeNode || {
          layout: {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
            rotate: 0,
          },
        }
      );
    });
    const activeNodeLayout = computed({
      get() {
        return activeNode.value.layout;
      },
      set(val) {
        nodeTreeStore.activeNode.layout = val;
      },
    });
    const handleNode = (event, node) => {
      nodeTreeStore.resizeTemporaryGroup();
      setActive(node);
      // nextTick(() => {
      //   shapeRef.value.mousedown(event, 'move');
      // });
    };
    const handleTemporaryGroup = () => {
      setActive(nodeTreeStore.temporaryGroup);
      // nextTick(() => {
      //   shapeRef.value.mousedown(event, 'move');
      // });
    };
    const dbClickTemporaryGroup = (event) => {
      console.log(event);
      let x = event.layerX;
      let y = event.layerY;
      let node = nodeTreeStore.temporaryGroup.children.reduce((pre, cur) => {
        if (
          cur.layout.x <= x &&
          cur.layout.x + cur.layout.width >= x &&
          cur.layout.y <= y &&
          cur.layout.y + cur.layout.height >= y
        ) {
          if (!pre) return cur;
          if (cur.layout.zIndex > pre.layout.zIndex) {
            return cur;
          } else {
            return pre;
          }
        } else {
          return pre;
        }
      }, undefined);
      if (node) {
        nodeTreeStore.resizeTemporaryGroup(); // 清空临时组
        setActive(node);
      }
    };
    const deleteNode = () => {
      nodeTreeStore.deleteNode(nodeTreeStore.activeNode);
    };
    const isActive = computed(() => {
      return nodeTreeStore.activeNode && nodeTreeStore.activeNode.id !== nodeTreeStore.root.id;
    });
    const dbClick = (event) => {
      let x = event.layerX;
      let y = event.layerY;
      console.log(nodeTreeStore.activeNode);
      if (!nodeTreeStore.activeNode.children) return;
      let child = nodeTreeStore.activeNode.children.reduce((pre, cur) => {
        if (
          cur.layout.x <= x &&
          cur.layout.x + cur.layout.width >= x &&
          cur.layout.y <= y &&
          cur.layout.y + cur.layout.height >= y
        ) {
          if (!pre) return cur;
          if (cur.layout.zIndex > pre.layout.zIndex) {
            return cur;
          } else {
            return pre;
          }
        } else {
          return pre;
        }
      }, undefined);
      if (child) {
        nodeTreeStore.resizeTemporaryGroup(); // 清空临时组
        setActive(child);
      }
    };
    return {
      nodeTreeStore,
      el,
      style,
      dragover,
      drop,
      dragenter,
      pageWidth,
      pageHeight,
      // DraggableContainerHeight,
      // DraggableContainerWidth,
      pages,
      showPages,
      mousedown,
      setActive,
      activeNode,
      activeNodeLayout,
      shapeRef,
      handleNode,
      deleteNode,
      handleTemporaryGroup,
      isActive,
      dbClickTemporaryGroup,
      dbClick,
    };
  },
});
</script>
<template>
  <div id="tree_root" class="root">
    <div
      :style="style"
      @dragenter="dragenter"
      @dragover="dragover"
      @drop="drop"
      :prevent-default="true"
      id="a4"
      ref="el"
    >
      <div
        v-for="page in pages"
        :key="page"
        class="tw-w-full tw-border-dashed tw-border tw-border-gray-300 tw-left-0 text-primary"
        :style="{
          height: '1px',
          top: page * 1123 + 'px',
          position: 'absolute',
        }"
      >
        {{ page + 1 }}
      </div>
      <div
        @mousedown="mousedown"
        :style="{
          width: pageWidth + 'px',
          height: pageHeight + 'px',
          position: 'relative',
          overflow: 'hidden',
        }"
      >
        <TemporaryGroup @mousedown.stop.prevent="handleTemporaryGroup"></TemporaryGroup>
        <RenderCom
          @dblclick.stop.prevent="dbClick($event, child)"
          v-for="child in nodeTreeStore.root.children"
          :node="child"
          :key="child.id"
        />
      </div>
      <LinesComponent v-if="true"></LinesComponent>
      <Shape
        @dblclick.stop.prevent="dbClick"
        :allow-rotation="activeNode.rotate"
        v-if="isActive"
      ></Shape>
      <Teleport v-if="nodeTreeStore.activeNodeId === nodeTreeStore.root.id" to="#layout-form" defer>
        <q-form>
          <template v-if="nodeTreeStore.activeNodeId === nodeTreeStore.root.id">
            <q-input v-model="nodeTreeStore.root.label"></q-input>
            <!-- <q-input v-model="nodeTreeStore.root.layout.padding" type="number" label="页边距" /> -->
            <q-toggle v-model="nodeTreeStore.root.scope" label="限制活动范围"></q-toggle>
            <q-toggle v-model="showPages" label="分页辅助线" />
            <q-btn-group class="tw-mt-10px tw-w-full">
              <q-btn
                style="flex: 1"
                @click="nodeTreeStore.root.layout.height += 1123"
                label="增加一页"
              ></q-btn>
              <q-btn
                style="flex: 1"
                :disable="nodeTreeStore.root.layout.height <= 1123"
                @click="nodeTreeStore.root.layout.height -= 1123"
                label="减少一页"
              ></q-btn>
            </q-btn-group>
          </template>
          <!-- <template v-else>
            <div>
              <q-toolbar class="tw-text-black rounded-borders">
                <q-toolbar-title>{{ activeNode.label }}</q-toolbar-title>
                <q-btn-group padding="sm" class="fab-btn" square flat dense>
                  <q-btn square flat @click="deleteNode" dense color="negative" icon="delete" />
                </q-btn-group>
              </q-toolbar>
              <div class="q-pa-md row q-gutter-md">
                <q-input class="col" v-model="activeNodeLayout.width" type="number" label="宽" />
                <q-input class="col" v-model="activeNodeLayout.height" type="number" label="高" />
              </div>
              <div class="q-pa-md row q-gutter-md">
                <q-input class="col" v-model="activeNodeLayout.x" type="number" label="x" />
                <q-input class="col" v-model="activeNodeLayout.y" type="number" label="y" />
              </div>
              <div class="q-pa-md row q-gutter-md">
                <q-input class="col" v-model="activeNodeLayout.zIndex" type="number" label="层级" />
                <q-input
                  class="col"
                  v-model="activeNodeLayout.rotate"
                  type="number"
                  label="旋转角度"
                />
              </div>
            </div>
          </template> -->
        </q-form>
      </Teleport>
      <!-- <Teleport v-if="nodeTreeStore.activeNodeId === nodeTreeStore.root.id" to="#layout-form" defer>
        <q-form>
          <q-input v-model="nodeTreeStore.root.layout.padding" type="number" label="页边距" />
          <q-toggle v-model="showPages" label="分页辅助线" />
          <q-btn-group class="tw-mt-10px tw-w-full">
            <q-btn
              style="flex: 1"
              @click="nodeTreeStore.root.layout.height += 1123"
              label="增加一页"
            ></q-btn>
            <q-btn
              style="flex: 1"
              :disable="nodeTreeStore.root.layout.height <= 1123"
              @click="nodeTreeStore.root.layout.height -= 1123"
              label="减少一页"
            ></q-btn>
          </q-btn-group>
        </q-form>
      </Teleport> -->
    </div>
  </div>
</template>
<style lang="scss" scoped>
@media print {
  // 设置纸张为A4
  @page {
    size: A4;
    padding: 0;
    margin: 0;
  }
  body {
    width: 210mm;
  }
  div {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
    color-adjust: exact;
  }
}
.root {
  height: auto;
  width: max-content;
  // 去除滚动条
  &::-webkit-scrollbar {
    display: none;
  }
}

#a4 {
  position: relative;
}
</style>
